<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Shop\Controller;

use Admin\Data\Common;
use Admin\Entity\Delivery;
use Admin\Service\Common\ExpressApi;
use Doctrine\ORM\EntityManager;
use Goods\Entity\GoodsVirtual;
use Laminas\Mvc\I18n\Translator;
use Laminas\View\Model\JsonModel;
use Operation\Service\UserCouponManager;
use Sales\Entity\Order;
use Sales\Entity\OrderDeliveryAddress;
use Sales\Entity\OrderDiscountRecord;
use Sales\Entity\OrderGoods;
use Sales\Entity\OrderGoodsEvaluation;
use Sales\Entity\OrderSelfLocation;
use Sales\Entity\OrderStatus;
use Sales\Service\OrderChangeAmountManager;
use Sales\Service\OrderDeliveryAddressManager;
use Sales\Service\OrderDiscountRecordManager;
use Sales\Service\OrderGoodsEvaluationBaseManager;
use Sales\Service\OrderGoodsEvaluationManager;
use Sales\Service\OrderGoodsManager;
use Sales\Service\OrderManager;
use Sales\Service\OrderSelfLocationManager;
use Sales\Service\OrderStatusManager;
use Shop\Form\OrderGoodsEvaluationForm;
use User\Entity\UserIntegralConfirm;
use User\Service\UserIntegralConfirmManager;

class HomeOrderController extends HomeActionController
{
    private $translator;
    private $entityManager;
    private $writeEntityManager;
    private $orderManager;
    private $orderStatusManager;
    private $orderDeliveryAddressManager;
    private $orderGoodsManager;
    private $orderSelfLocationManager;
    private $orderChangeAmountManager;
    private $orderGoodsEvaluationManager;
    private $orderGoodsEvaluationBaseManager;
    private $userIntegralConfirmManager;
    private $orderDiscountRecordManager;
    private $userCouponManager;

    public function __construct(
        Translator      $translator,
        EntityManager   $entityManager,
        EntityManager   $writeEntityManager,
        OrderManager    $orderManager,
        OrderStatusManager $orderStatusManager,
        OrderDeliveryAddressManager $orderDeliveryAddressManager,
        OrderGoodsManager           $orderGoodsManager,
        OrderSelfLocationManager    $orderSelfLocationManager,
        OrderChangeAmountManager    $orderChangeAmountManager,
        OrderGoodsEvaluationManager $orderGoodsEvaluationManager,
        OrderGoodsEvaluationBaseManager $orderGoodsEvaluationBaseManager,
        UserIntegralConfirmManager  $userIntegralConfirmManager,
        OrderDiscountRecordManager  $orderDiscountRecordManager,
        UserCouponManager   $userCouponManager
    )
    {
        $this->translator           = $translator;
        $this->entityManager        = $entityManager;
        $this->orderManager         = $orderManager;
        $this->writeEntityManager   = $writeEntityManager;
        $this->orderStatusManager   = $orderStatusManager;
        $this->orderDeliveryAddressManager  = $orderDeliveryAddressManager;
        $this->orderGoodsManager    = $orderGoodsManager;
        $this->orderSelfLocationManager     = $orderSelfLocationManager;
        $this->orderChangeAmountManager     = $orderChangeAmountManager;
        $this->orderGoodsEvaluationManager  = $orderGoodsEvaluationManager;
        $this->orderGoodsEvaluationBaseManager = $orderGoodsEvaluationBaseManager;
        $this->userIntegralConfirmManager   = $userIntegralConfirmManager;
        $this->orderDiscountRecordManager   = $orderDiscountRecordManager;
        $this->userCouponManager    = $userCouponManager;
    }

    /**
     * 订单列表
     * @return array|\Laminas\View\Model\ViewModel
     */
    public function indexAction()
    {
        $this->layout()->setVariable('titleName', $this->translator->translate('我的订单'));

        $searchArray = [];
        $orderStatus= $this->params()->fromQuery('orderStatus', -1);

        $searchArray['orderStatus'] = $orderStatus;

        $page       = (int) $this->params()->fromQuery('page', 1);
        $query      = $this->entityManager->getRepository(Order::class)->shopFindMyOrderList(parent::$userId, $searchArray);
        $paginator  = $this->shopPlugin()->shopPaginator($query, $page);

        //动态绑定的快递id数组
        $deliveryIdArray = $this->shopPlugin()->getExpressCodeIdArray();

        return ['orderList' => $paginator, 'orderStatus' => $orderStatus, 'deliveryIdArray' => $deliveryIdArray];
    }

    /**
     * 订单详情
     * @return array|\Laminas\Http\Response
     */
    public function orderInfoAction()
    {
        $this->layout()->setVariable('titleName', $this->translator->translate('订单详情'));

        $orderId    = (int) $this->params()->fromRoute('id', 0);
        $orderInfo  = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId, 'userId' => parent::$userId]);
        if($orderInfo == null) return $this->redirect()->toRoute('shop-home');

        //自提点信息，只有配送方式为自提时才有信息
        $orderSelfLocation = $this->entityManager->getRepository(OrderSelfLocation::class)->findOneBy(['orderId' => $orderId]);

        //配送地址
        $orderDeliveryAddress = $this->entityManager->getRepository(OrderDeliveryAddress::class)->findOneBy(['orderId' => $orderId]);

        //可获取积分
        $integral = $this->entityManager->getRepository(UserIntegralConfirm::class)->findOneBy(['id' => $orderInfo->getOrderId(), 'userId' => parent::$userId, 'confirmType' => 'order']);

        //订单状态历史
        $orderStatus = $this->entityManager->getRepository(OrderStatus::class)->findBy(['orderId' => $orderId], ['statusId' => 'ASC']);

        //订单优惠记录
        $orderDiscountRecord = $this->entityManager->getRepository(OrderDiscountRecord::class)->findBy(['orderId' => $orderId, 'userId' => parent::$userId]);

        //动态绑定的快递id数组
        $deliveryIdArray = $this->shopPlugin()->getExpressCodeIdArray();

        return [
            'orderInfo'             => $orderInfo,
            'orderDeliveryAddress'  => $orderDeliveryAddress,
            'orderSelfLocation'     => $orderSelfLocation,
            'integral'              => $integral,
            'orderStatus'           => $orderStatus,
            'orderDiscountRecord'   => $orderDiscountRecord,
            'deliveryIdArray'       => $deliveryIdArray
        ];
    }

    /**
     * 订单确认收货
     * @return mixed
     */
    public function receiptOrderAction()
    {
        $orderId = (int) $this->params()->fromRoute('id', 0);
        $orderInfo  = $this->writeEntityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId, 'userId' => parent::$userId]);
        if(
            $orderInfo == null
            || $orderInfo->getOrderStatus() < $this->shopPlugin()->getOrderStatusCode('GOODS_SHIPPED')
            || $orderInfo->getOrderStatus() >= $this->shopPlugin()->getOrderStatusCode('GOODS_RECEIVED')
        ) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单不能进行收货处理!'));
            return $this->shopPlugin()->toReferer();
        }

        $this->writeEntityManager->beginTransaction();
        try {
            $orderInfo = $this->orderManager->editOrder(['orderStatus' => $this->shopPlugin()->getOrderStatusCode('GOODS_RECEIVED'), 'orderFinishTime' => time()], $orderInfo);
            $this->orderStatusManager->addOrderStatus(['orderStatus' => $orderInfo->getOrderStatus(), 'operateUser' => parent::$userName, 'orderId' => $orderInfo->getOrderId(), 'statusInfo' => $this->translator->translate('买家确认收货'), 'statusTime' => $orderInfo->getOrderFinishTime()]);
            $this->getEventManager()->trigger('shop.order.receipt.post', $this, ['orderInfo' => $orderInfo]);
            $this->writeEntityManager->commit();
            $this->flashMessenger()->addSuccessMessage($this->translator->translate('订单收货处理成功!'));

            return $this->redirect()->toRoute('home-order', ['action' => 'finishReceiptOrder', 'id' => $orderId]);
            //return $this->redirect()->toRoute('home-order', [], ['query' => ['orderStatus' => $this->shopPlugin()->getOrderStatusCode('goods_received') . '-' . $this->shopPlugin()->getOrderStatusCode('complete')]]);
        } catch (\Exception $e) {
            $this->writeEntityManager->rollback();
            $this->flashMessenger()->addWarningMessage($this->translator->translate('订单收货处理失败!'));
        }

        return $this->shopPlugin()->toReferer();
    }

    /**
     * 订单确认完成后的页面显示
     * @return array|\Laminas\Http\Response
     */
    public function finishReceiptOrderAction()
    {
        $orderId = (int) $this->params()->fromRoute('id', 0);
        $orderInfo  = $this->writeEntityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId, 'userId' => parent::$userId]);
        if ($orderInfo->getOrderStatus() < $this->shopPlugin()->getOrderStatusCode('GOODS_RECEIVED')) return $this->redirect()->toRoute('shop-home');

        return ['orderInfo' => $orderInfo];
    }

    /**
     * 取消订单
     * @return mixed
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function cancelOrderAction()
    {
        if(!$this->shopPlugin()->validatorQueryCsrf()) return $this->shopPlugin()->toReferer();

        $orderId    = (int) $this->params()->fromRoute('id', 0);
        $orderInfo  = $this->writeEntityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId, 'userId' => parent::$userId]);
        if(
            $orderInfo == null
            || ($orderInfo->getPaymentType() == 'OnlinePay' && $orderInfo->getOrderStatus() >= $this->shopPlugin()->getOrderStatusCode('WAIT_GOODS_ARRIVE'))
            || ($orderInfo->getPaymentType() == 'CashOnDelivery' && $orderInfo->getOrderStatus() >= $this->shopPlugin()->getOrderStatusCode('GOODS_SHIPPED'))
            || $orderInfo->getOrderStatus() == $this->shopPlugin()->getOrderStatusCode('CANCEL_ORDER')
        ) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单不能取消!'));
            return $this->shopPlugin()->toReferer();
        }

        $this->writeEntityManager->beginTransaction();
        try {
            $orderInfo = $this->orderManager->editOrder(['orderStatus' => $this->shopPlugin()->getOrderStatusCode('cancel_order')], $orderInfo);
            $this->orderStatusManager->addOrderStatus(['orderStatus' => $orderInfo->getOrderStatus(), 'operateUser' => parent::$userName, 'orderId' => $orderInfo->getOrderId(), 'statusInfo' => $this->translator->translate('订单取消'), 'statusTime' => time()]);
            $this->getEventManager()->trigger('shop.order.cancel.post', $this, ['orderInfo' => $orderInfo]);
            $this->writeEntityManager->commit();
            $this->flashMessenger()->addSuccessMessage($this->translator->translate('订单取消成功!'));
        } catch (\Exception $e) {
            $this->writeEntityManager->rollback();
            $this->flashMessenger()->addWarningMessage($this->translator->translate('订单取消失败!'));
        }

        return $this->shopPlugin()->toReferer();
    }

    /**
     * 订单删除
     * @return \Laminas\Http\Response
     */
    public function deleteOrderAction()
    {
        if(!$this->shopPlugin()->validatorQueryCsrf()) return $this->shopPlugin()->toReferer();

        $orderId    = (int) $this->params()->fromRoute('id', 0);
        $orderInfo  = $this->writeEntityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId, 'userId' => parent::$userId]);
        if($orderInfo == null || $orderInfo->getOrderStatus() != $this->shopPlugin()->getOrderStatusCode('CANCEL_ORDER')) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单不能删除!'));
            return $this->shopPlugin()->toReferer();
        }

        $this->writeEntityManager->beginTransaction();
        try {
            $this->orderManager->deleteOrder($orderInfo);
            $this->orderStatusManager->deleteOrderStatus($orderId);
            $this->orderGoodsManager->deleteOrderGoods($orderId);
            $this->orderDeliveryAddressManager->deleteOrderDeliveryAddress($orderId);
            $this->orderChangeAmountManager->deleteOrderChangeAmount($orderId);
            $this->orderSelfLocationManager->deleteOrderSelfLocation($orderId);
            $this->userIntegralConfirmManager->deleteUserIntegralConfirm($orderId, 'order');
            $this->userCouponManager->deleteUserOrderCoupon($orderId);
            $this->orderDiscountRecordManager->deleteOrderDiscountRecord($orderId);
            $this->writeEntityManager->commit();
            $this->flashMessenger()->addSuccessMessage($this->translator->translate('订单删除成功!'));
        } catch (\Exception $e) {
            $this->writeEntityManager->rollback();
            $this->flashMessenger()->addWarningMessage($this->translator->translate('订单删除失败!'));
            return $this->shopPlugin()->toReferer();
        }
        return $this->redirect()->toRoute('home-order');
    }

    /**
     * 物流轨迹查看
     * @return array[]|\Laminas\Http\Response|mixed
     */
    public function orderExpressTrackAction()
    {
        if (Common::configValue('deliveryApiState', 'delivery') != 1) return $this->response->setContent($this->translator->translate('物流轨迹已经关闭，无法查看'));

        $this->layout()->setVariable('titleName', $this->translator->translate('物流轨迹'));

        $orderId    = (int) $this->params()->fromRoute('id', 0);
        $orderInfo  = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderId, 'userId' => parent::$userId]);
        if($orderInfo == null) return $this->redirect()->toRoute('shop-home');

        $expressContent = null;
        if ($orderInfo->getDeliveryMode() == 1) {//统一模式
            if (!empty($orderInfo->getExpressNumber())) {
                $deliveryInfo = $this->entityManager->getRepository(Delivery::class)->findOneBy(['deliveryId' => $orderInfo->getDeliveryId()]);
                if (!empty($deliveryInfo->getDeliveryNameCode())) $expressContent = ExpressApi::expressQuery($deliveryInfo->getDeliveryNameCode(), $orderInfo->getExpressNumber());
            }
        } elseif ($orderInfo->getDeliveryMode() == 2) {//单独配送模式
            $deliveryIdArray = $this->shopPlugin()->getExpressCodeIdArray();
            foreach ($orderInfo->getOrderGoods() as $key => $goodsValue) {
                $expressContent['goods'][$key] = [
                    'goodsName'     => $goodsValue->getGoodsName(),
                    'deliveryName'  => $goodsValue->getDeliveryName(),
                    'expressNumber' => $goodsValue->getExpressNumber()
                ];
                if ($goodsValue->getGoodsType() == 1 && $goodsValue->getDeliveryId() > 0 && isset($deliveryIdArray[$goodsValue->getDeliveryId()])) {
                    $expressContent['goods'][$key]['expressContent'] = ExpressApi::expressQuery($deliveryIdArray[$goodsValue->getDeliveryId()], $goodsValue->getExpressNumber());
                }
            }
        }

        return ['expressContent' => $expressContent];
    }

    /**
     * 订单商品评价
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function orderGoodsEvaluationAction()
    {
        $orderGoodsId = (int) $this->params()->fromRoute('id', 0);
        $orderGoodsInfo = $this->writeEntityManager->getRepository(OrderGoods::class)->findOneBy(['orderGoodsId' => $orderGoodsId, 'userId' => parent::$userId]);
        if($orderGoodsInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单商品不存在!'));
            return $this->shopPlugin()->toReferer();
        }

        $orderInfo = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderGoodsInfo->getOrderId(), 'userId' => parent::$userId]);
        if($orderInfo == null || $orderInfo->getOrderStatus() < $this->shopPlugin()->getOrderStatusCode('GOODS_RECEIVED')) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('确认收货后的订单商品才可以评价!'));
            return $this->shopPlugin()->toReferer();
        }

        if($orderGoodsInfo->getEvaluationStatus() == 1) {
            $goodsEvaluation = $this->entityManager->getRepository(OrderGoodsEvaluation::class)->findOneBy(['orderGoodsId' => $orderGoodsId]);
            $array = ['goodsEvaluation' => $goodsEvaluation, 'orderInfo' => $orderInfo, 'orderGoodsInfo' => $orderGoodsInfo];
        } else {
            $form = new OrderGoodsEvaluationForm();
            if($this->getRequest()->isPost()) {
                $data = $this->params()->fromPost();
                $form->setData($data);
                if ($form->isValid()) {
                    $data = $form->getData();
                    $data['userId']     = parent::$userId;
                    $data['userName']   = parent::$userName;
                    $data['evaluationTime'] = time();
                    $data['goodsId']    = $orderGoodsInfo->getGoodsId();
                    $data['orderGoodsId']   = $orderGoodsInfo->getOrderGoodsId();
                    $this->orderGoodsEvaluationManager->addEvaluation($data);
                    $this->orderGoodsEvaluationBaseManager->editOrderGoodsEvaluationBase(['userName' => $data['userName'], 'time' => $data['evaluationTime']], $data['goodsId']);
                    $this->orderGoodsManager->editOrderGoods(['evaluationStatus' => 1], $orderGoodsInfo);

                    return $this->redirect()->toRoute('home-order', ['action' => 'orderGoodsEvaluationFinish', 'id' => $orderGoodsId]);
                }
            }

            $array = ['form' => $form, 'orderInfo' => $orderInfo, 'orderGoodsInfo' => $orderGoodsInfo];
        }

        return $array;
    }

    /**
     * 评价完成页面
     * @return array|\Laminas\Http\Response
     */
    public function orderGoodsEvaluationFinishAction()
    {
        $orderGoodsId = (int) $this->params()->fromRoute('id', 0);
        $orderGoodsInfo = $this->writeEntityManager->getRepository(OrderGoods::class)->findOneBy(['orderGoodsId' => $orderGoodsId, 'evaluationStatus' => 1, 'userId' => parent::$userId]);
        if($orderGoodsInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该订单商品不存在!'));
            return $this->redirect()->toRoute('home-order');
        }

        return ['orderGoodsInfo' => $orderGoodsInfo];
    }

    /**
     * 我的虚拟商品列表
     * @return array
     */
    public function orderGoodsVirtualAction()
    {
        $this->layout()->setVariable('titleName', $this->translator->translate('我的虚拟商品'));

        $page       = (int) $this->params()->fromQuery('page', 1);
        $query      = $this->entityManager->getRepository(OrderGoods::class)->shopVirtualGoodsList(parent::$userId);
        $paginator  = $this->shopPlugin()->shopPaginator($query, $page);

        return ['goodsVirtualList' => $paginator];
    }

    /**
     * 虚拟商品详情
     * @return array|\Laminas\Http\Response
     */
    public function viewVirtualGoodsAction()
    {
        $this->layout()->setVariable('titleName', $this->translator->translate('虚拟商品详情'));

        $orderGoodsId   = (int) $this->params()->fromRoute('id', 0);
        $orderGoodsInfo = $this->entityManager->getRepository(OrderGoods::class)->findOneBy(['orderGoodsId' => $orderGoodsId, 'userId' => parent::$userId, 'goodsType' => 2]);
        if ($orderGoodsInfo == null) return $this->redirect()->toRoute('shop-home');

        $orderInfo      = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderGoodsInfo->getOrderId()]);
        $virtualGoods   = $this->entityManager->getRepository(GoodsVirtual::class)->findBy(['orderId' => $orderGoodsInfo->getOrderId(), 'userId' => parent::$userId, 'goodsId' => $orderGoodsInfo->getGoodsId()]);

        return ['orderGoodsInfo' => $orderGoodsInfo, 'orderInfo' => $orderInfo, 'virtualGoods' => $virtualGoods];
    }

    /**
     * 获取订单的支付状态
     * @return JsonModel
     */
    public function ajaxOrderPaymentStatusAction()
    {
        $orderSn = $this->params()->fromQuery('orderSn');
        if(!empty($orderSn) && parent::$userId) {
            $orderInfo = $this->entityManager->getRepository(Order::class)->findOneBy(['orderSn' => $orderSn, 'userId' => parent::$userId]);
            if($orderInfo && $orderInfo->getOrderStatus() >= $this->shopPlugin()->getOrderStatusCode('WAIT_GOODS_ARRIVE')) return new JsonModel(['state' => 'true']);
        }
        return new JsonModel(['state' => 'false']);
    }
}